package xj.graph2d.app.prop;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import xj.graph2d.DrawShape;
import xj.graph2d.GraphDocument;
import xj.graph2d.ModelListener;
import xj.graph2d.SimpleDrawDocument;
import xj.graph2d.app.DrawApp;
import xj.meta.ModelElement;
import xj.model.uml.UMLDiagram;

import static xj.app.BaseApplicationFrame.getResourceString;

public abstract class PropertiesPane extends JPanel {

  public PropertiesPane(DrawApp main) {
    this(0, main);
  }

  public PropertiesPane(int n, DrawApp main) {
    this.main = main;
    //setBackground(UIManager.getColor("window"));
    if (n > 0) {
      propEntries = new ArrayList<PropertyEntry>(n);
    } else {
      propEntries = new ArrayList<PropertyEntry>();
    }

    setLayout(new BorderLayout());
    mainPanel = new GridPanel();
    add(new JScrollPane(mainPanel), BorderLayout.CENTER);
  }

  protected void addRow(String left, JComponent right,
			ModelPropertyField field, int pos) {
    if (propEntries != null && right != null) {
      mainPanel.addRow(left, right, pos);
      propEntries.add(new PropertyEntry(left, right, field));
    }
  }

  public void addRow(JComponent comp) {
    addRow(comp, null);
  }

  public void addRow(JComponent comp, ModelPropertyField[] fields) {
    if (comp != null) {
      mainPanel.addRow(comp, GridBagConstraints.CENTER);
      if (fields != null) {
	addModelPropertyFields(fields);
      }
    }
  }

  public void addRow(ModelPropertyField field) {
    if (field != null) {
      JComponent comp = field.getEditor();
      if (comp != null) { 
	comp.setName(field.getFieldName());
      }
      addRow(field.getDisplayName(), comp, field,
	     GridBagConstraints.WEST);
    }
  }

  public void addFiller() {
    mainPanel.addFiller();
  }

  public void addModelPropertyFields(ModelPropertyField[] fields) {
    if (fields != null) {
      int n = fields.length;
      for (int i = 0; i < n; i++) {
	ModelPropertyField f = fields[i];
	if (f != null) {
	  propEntries.add(new PropertyEntry(f.getDisplayName(), f.getEditor(), f));
	}
      }
    }
  }

  public void setDrawShape(DrawShape shape, DrawApp main) {
    if (debug) { 
      System.out.println("PropertiesPane.setDrawShape() @1");
    }

    curShape = shape;
    this.main = main;
    if (shape != null) {
      ModelListener ml = shape.getModelListener();
      if (ml != null) {
	if (debug) { 
	  System.out.println("PropertiesPane.setDrawShape() modelListener != null");
	}
	ml.updateModel();
      }

      if (debug) { 
	System.out.println("PropertiesPane.setDrawShape() @2");
      }

      model = shape.getModel();
    } else { 
      model = getCurrentUMLDiagram();
    }
    if (model != null) { 
      setValues();
    }

    if (debug) { 
      System.out.println("PropertiesPane.setDrawShape() @3");
    }
  }

  public void setValues() {
    setEditingMode(false);
    if (model != null && propEntries != null) {
      int n = propEntries.size();
      for (int i = 0; i < n; i++) {
	PropertyEntry e = propEntries.get(i);
	if (e != null) {
	  ModelPropertyField field = e.field;
	  if (field != null) {
	    field.setModel(model);
	    field.setShape(curShape);
	    field.setMain(main);
	    field.updateEditorValue();
	  }
	}
      }
    }
    setEditingMode(true);
  }

  protected void setEditingMode(Boolean b) { 
    if (model != null && propEntries != null) {
      int n = propEntries.size();
      for (int i = 0; i < n; i++) {
	PropertyEntry e = propEntries.get(i);
	if (e != null) {
	  ModelPropertyField field = e.field;
	  field.setEditingMode(b);
	}
      }
    }
  }

  public String getTitleString() {
    if (curShape != null) {
      String titleString = curShape.getDisplayName();
      if (titleString == null) {
	String tempName = curShape.getTemplateName();
	String name1 = tempName;
	String name2 = tempName;
	if (tempName != null) {
	  int i = tempName.indexOf('.');
	  if (i > 0) {
	    name1 = tempName.substring(0, i);
	    name2 = tempName.substring(i + 1);
	  }
	}
	String displayTempName = getResourceString("template." + tempName + ".title");
	
	if (displayTempName != null) {
	  titleString = displayTempName;
	} else if (name2 != null && name2.length() > 0) {
	  titleString = name2;
	}
      } else {
	String text = getResourceString(titleString + ".text");
	if (text != null && text.length() > 0) { 
	  titleString = text;
	}
      }
      return titleString;
    } else {
      if (model instanceof UMLDiagram) {
	UMLDiagram diagram = (UMLDiagram) model; 
	return diagram.getType().toString().replaceAll("_", " ");
      }
      return "UML Diagram";
    }
  }

  public UMLDiagram getCurrentUMLDiagram() {
    if (main != null) {
      SimpleDrawDocument doc = main.getDoc();
      if (doc instanceof GraphDocument) {
	GraphDocument gdoc = (GraphDocument) doc;
	ModelElement model = gdoc.getModel();
	if (model instanceof UMLDiagram) {
	  return (UMLDiagram) model;
	}
      }
    }
    return null;
  }

  public JComponent getPropertyComponent(String name) { 
    if (name != null) { 
      for (PropertyEntry e : propEntries) { 
	if (name.equals(e.name)) {
	  return e.value;
	}
      }
    }
    return null;
  } 

  protected GridPanel mainPanel;

  protected List<PropertyEntry> propEntries;

  protected DrawShape curShape;

  protected ModelElement model;

  protected DrawApp main;

  protected static boolean debug = false;

  static class PropertyEntry {

    PropertyEntry(JComponent value) {
      this(null, value, null);
    }

    PropertyEntry(String name, JComponent value) {
      this(name, value, null);
    }

    PropertyEntry(String name, JComponent value, ModelPropertyField field) {
      this.name = name;
      this.value = value;
      this.field = field;
    }

    protected String name;

    protected JComponent value;

    protected ModelPropertyField field;

  }

}
